from flask import g, redirect, render_template, abort, request, jsonify, current_app

from info import db
from info.common import user_login_data, img_upload
from info.constants import USER_COLLECTION_MAX_NEWS, USER_FOLLOWED_MAX_COUNT, QINIU_DOMIN_PREFIX
from info.models import tb_user_collection, Category, News
from info.modules.user import user_blu
from info.utils.response_code import RET, error_map


# 显示个人中心
@user_blu.route('/user_info')
@user_login_data
def user_info():
    user = g.user
    if not user:
        # 用户未登录则重定向到主页面
        return redirect('/')
    return render_template('news/user.html', user=user.to_dict())


# 显示/修改基本资料
@user_blu.route('/base_info', methods=['GET', 'POST'])
@user_login_data
def base_info():
    user = g.user
    if not user:
        return abort(403)
    if request.method == 'GET':
        return render_template('news/user_base_info.html', user=user.to_dict())

    # 获取参数
    signature = request.json.get('signature')
    nick_name = request.json.get('nick_name')
    gender = request.json.get('gender')
    # 校验参数
    if not all([signature, nick_name, gender]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    if gender not in ['MAN', 'WOMAN']:
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    # 修改模型数据
    user.signature = signature
    user.nick_name = nick_name
    user.gender = gender
    # 返回json
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])


# 显示/修改头像
@user_blu.route('/pic_info', methods=['GET', 'POST'])
@user_login_data
def pic_info():
    user = g.user
    if not user:
        return abort(403)
    if request.method == 'GET':
        return render_template('news/user_pic_info.html', user=user.to_dict())
    # post处理
    try:
        img_bytes = request.files.get('avatar').read()
        # 将接收到的文件上传到文件服务器
        try:
            file_name = img_upload(img_bytes)
            user.avatar_url = file_name  # 修改数据图中用户图片的路径

        except BaseException as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.THIRDERR, errmsg=error_map[RET.THIRDERR])

    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 将用户信息返回给前端，以便前端更新图片
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK], data=user.to_dict())


# 显示/修改密码
@user_blu.route('/pass_info', methods=['GET', 'POST'])
@user_login_data
def pass_info():
    user = g.user
    if not user:
        return abort(403)
    if request.method == 'GET':
        return render_template('news/user_pass_info.html')

    # post处理
    old_password = request.json.get('old_password')
    new_password = request.json.get('new_password')

    if not all([old_password, new_password]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    # 校验旧密码是否正确
    if not user.check_password(old_password):
        return jsonify(errno=RET.PWDERR, errmsg=error_map[RET.PWDERR])
    # 修改密码
    user.password = new_password
    # json返回
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])


# 显示我的收藏
@user_blu.route('/collection')
@user_login_data
def collection():
    user = g.user
    if not user:
        return abort(403)
    # 获取参数
    page = request.args.get('p', 1)
    try:
        page = int(page)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    news_list = list()
    cur_page = 1
    total_page = 1
    # 查询用户所有收藏的新闻按照收藏时间倒序排列,并传到模板中进行模板替换
    try:
        pn = user.collection_news.order_by(tb_user_collection.c.create_time.desc()).paginate(page, USER_COLLECTION_MAX_NEWS)
        news_list = pn.items
        cur_page = pn.page
        total_page = pn.pages
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])

    data = {
        'news_list': [news.to_dict() for news in news_list],
        'cur_page': cur_page,
        'total_page': total_page
    }

    return render_template('news/user_collection.html', data=data)


# 显示新闻发布页面/提交页面
@user_blu.route('/news_release', methods=['GET', 'POST'])
@user_login_data
def news_release():
    user = g.user
    if not user:
        return abort(403)

    if request.method == 'GET':
        # 查询所有分类，传到模板中
        categories = list()
        try:
            categories = Category.query.all()
        except BaseException as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])

        if len(categories):
            categories.pop(0)

        return render_template('news/user_news_release.html', categories=categories)
    # post处理 获取参数
    title = request.form.get('title')
    category_id = request.form.get('category_id')
    digest = request.form.get('digest')
    content = request.form.get('content')
    # 校验参数
    if not all([title, category_id, digest, content]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    try:
        category_id = int(category_id)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 创建新闻模型,保存到数据库中
    news = News()
    news.title = title
    news.category_id = category_id
    news.digest = digest
    news.content = content
    news.user_id = user.id  # 新闻作者id
    news.source = '个人发布'  # 新闻来源
    news.status = 1  # 设置新闻审核状态
    try:
        img_bytes = request.files.get('index_image').read()
        file_name = img_upload(img_bytes)
        news.index_image_url = QINIU_DOMIN_PREFIX + file_name
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    # 添加到数据库
    db.session.add(news)

    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])


# 显示我发布的新闻列表
@user_blu.route('/news_list')
@user_login_data
def news_list():
    user = g.user
    if not user:
        return abort(403)
    page = request.args.get('p', 1)
    try:
        page = int(page)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    news_list = list()
    total_page = 1
    cur_page = 1
    # 查询当前用户发布的所有新闻并传到模板中
    try:
        pn = user.news_list.order_by(News.create_time.desc()).paginate(page, USER_COLLECTION_MAX_NEWS)
        news_list = pn.items
        cur_page = pn.page
        total_page = pn.pages
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])

    data = {
        'news_list': [news.to_review_dict() for news in news_list],
        'cur_page': cur_page,
        'total_page': total_page
    }

    return render_template('news/user_news_list.html', data=data)


# 显示我的关注
@user_blu.route('/user_follow')
@user_login_data
def user_follow():
    user = g.user
    if not user:
        return abort(403)
    # 获取参数
    p = request.args.get('p', 1)
    try:
        p = int(p)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    author_list = list()
    cur_page = 1
    total_page = 1
    # 查询用户关注的作者，指定当前页码
    try:
        pn = user.followed.paginate(p, USER_COLLECTION_MAX_NEWS)
        author_list = [author.to_dict() for author in pn.items]
        cur_page = pn.page
        total_page = pn.pages
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])

    data = {
        'author_list': author_list,
        'cur_page': cur_page,
        'total_page': total_page
    }

    return render_template('news/user_follow.html', data=data)